import WebpackLicense from '@components/WebpackLicense';
import { ApiMeta, Stability } from '@components/ApiMeta.tsx';
import { Tabs, Tab } from '@theme';

<WebpackLicense from="https://webpack.docschina.org/guides/web-workers/" />

# Web Workers

Rspack 提供了对 [Web Workers](https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers) 的内置支持，这意味着你不需要任何的 Loader 就可以直接使用 Web Workers。

## 使用方式

基本的 Worker 创建语法：

```js
new Worker(new URL('./worker.js', import.meta.url));
```

通过 `name` 属性可以自定义 Worker 的 chunk 名称（需要属性值可被静态分析），此名称会替换生成的 chunk 文件名中的 `[name]` 占位符：

```js
new Worker(new URL('./worker.js', import.meta.url), {
  name: 'my-worker',
});
```

:::info
选择该语法的原因在于其具备良好的标准兼容性，它基于标准的 ECMAScript 模块规范，即使在没有构建工具的环境中也能正常运行。例如，它可以直接在支持 ES modules 的现代浏览器中执行。
:::

### 更多语法

除 `new Worker()` 以外，Rspack 还默认支持以下语法：

- `new SharedWorker()`，详见 [SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)。

```js
const sharedWorker = new SharedWorker(
  new URL('./shared-worker.js', import.meta.url),
);
sharedWorker.port.start();
```

- `import { Worker } from "node:worker_threads"`：常用于 Node.js 环境，详见 [Worker threads](https://nodejs.org/api/worker_threads.html)。

```js
import { Worker } from 'node:worker_threads';

const worker = new Worker(new URL('./node-worker.js', import.meta.url));
```

- `navigator.serviceWorker.register()`：用于注册 Service Worker，详见 [ServiceWorkerContainer](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register)。

```js
navigator.serviceWorker.register('./sw.js').then(registration => {
  console.log('Service worker registration succeeded:', registration);
});
```

如需支持更多自定义语法，可通过 [`module.parser.javascript.worker`](/config/module#moduleparserjavascriptworker) 配置实现。

### 示例

使用示例可参考：

- [examples/worker](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/worker)
- [examples/monaco-editor-js](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/monaco-editor-js)
- [examples/monaco-editor-ts-react](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/monaco-editor-ts-react)

### 注意事项

1. 需要注意的是 `new Worker` 也可以接受一个 URL 的字符串表示，但在 Rspack 中只支持传入 URL。
2. Rspack 不支持在 `new Worker` 中使用变量。例如，以下代码将不起作用：

   ```js
   const url = new URL('./path/to/worker.js', import.meta.url);
   const worker = new Worker(url);
   ```

   这是因为 Rspack 无法静态分析该语法。在 Rspack 中使用 Worker 语法时，请务必注意此限制。

3. 目前不支持 `/* webpackEntryOptions: { filename: "workers/[name].js" } */` 魔法注释。

## worker-loader

:::warning
`worker-loader` 仅作为项目迁移到 Rspack 的临时便捷方案，推荐使用 `new Worker()` 语法。
:::

Rspack 也支持了 worker-loader，不过由于 [worker-loader](https://github.com/webpack-contrib/worker-loader) 已不再维护，请使用 [worker-rspack-loader](https://github.com/rspack-contrib/worker-rspack-loader) 进行替换。

使用 [resolveLoader](/config/resolve-loader) 替换 worker-loader 为 worker-rspack-loader：

<Tabs>
  <Tab label="ESM">
```js title="rspack.config.mjs"
import { createRequire } from 'module';

const require = createRequire(import.meta.url);

export default {
  resolveLoader: {
    alias: {
      'worker-loader': require.resolve('worker-rspack-loader'),
    },
  },
};
```

  </Tab>
  <Tab label="CJS">

```js title="rspack.config.cjs"
module.exports = {
  resolveLoader: {
    alias: {
      'worker-loader': require.resolve('worker-rspack-loader'),
    },
  },
};
```

  </Tab>
</Tabs>
